cc.Class({
    extends: cc.Component,
    
        properties: {
            shadow: cc.SpriteFrame
        },
    
        onLoad() {
            cc.Popup = this;
            this.popups = {};
        },

        createShadow() {
            var node = new cc.Node();
            var spt = node.addComponent(cc.Sprite);
            var wgt = node.addComponent(cc.Widget);
            spt.spriteFrame = this.shadow;
            spt.type = cc.Sprite.Type.SLICED;
            wgt.isAlignTop = wgt.isAlignBottom = true;
            wgt.isAlignLeft = wgt.isAlignRight = true;
            wgt.top = wgt.bottom = wgt.left = wgt.right = 0;
            node.color = cc.color(0, 0, 0);
            node.cascadeOpacity = false;
            node.opacity = 160;
            return node;
        },
    
        show(prefab, showCbk, hideCbk) {
            if(typeof(prefab) === 'string') {
                if(!this.popups[prefab]) {
                    cc.loadRes(prefab, res => {
                        this.popups[prefab] = res;
                        this.show(res, showCbk, hideCbk);
                    });
                    return;
                } else prefab = this.popups[prefab];
            }
            var shadow = this.createShadow();
            shadow.parent = this.node;
            var popup = cc.instantiate(prefab);
            popup.parent = shadow;
            popup.scaleX = popup.scaleY = 0.6;
            popup.runAction(cc.scaleTo(0.3, 1).easing(cc.easeBackOut()));
            popup.on('close', () => this.hide(popup, hideCbk));
            popup.on('touchstart', event => event.stopPropagation());
            shadow.on('touchstart', event => {
                this.hide(popup, hideCbk);
                event.stopPropagation();
            }, this);
            showCbk && showCbk(popup.getComponent(prefab.name));
        },
    
        hide(popup, hideCbk) {
            popup.parent.runAction(cc.fadeOut(0.2));
            popup.runAction(cc.sequence(
                cc.scaleTo(0.2, 0.6, 0.6).easing(cc.easeExponentialIn()),
                cc.callFunc(() => {
                    popup.parent.destroy();
                    hideCbk && hideCbk();
                }, this)
            ))
        },
    });
    